﻿using Application.SaleReturn_hService;
using Domain.Entity.ord;
using Domain.Entity;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Application.PurchaseReturn_hService;
using Microsoft.Extensions.Caching.Distributed;
using OfficeOpenXml.FormulaParsing.Excel.Functions.Math;
using System.Text.Json;
using Application.ProductService;
using Application.PublicFileService;
using Application.PurchaseReturn_dService;
using System.Transactions;
using Application.SaleReturn_dService;
using WMSManage.Filter;

namespace WMSManage.Controllers
{
    [Route("api/[controller]/[action]")]
    [ApiController]
    [Authorize]//需要鉴权
    public class SaleReturn_hController : ControllerBase
    {
        private readonly ISaleReturn_hService saleReturn_HService;
        private readonly IDistributedCache distributedCache;
        private readonly IPublicFileService publicFileService;
        private readonly ISaleReturn_dService saleReturn_DService;
        private readonly IProductService productService;

        public SaleReturn_hController(ISaleReturn_hService saleReturn_HService,IDistributedCache distributedCache,IPublicFileService publicFileService,ISaleReturn_dService saleReturn_DService,IProductService productService)
        {
            this.saleReturn_HService = saleReturn_HService;
            this.distributedCache = distributedCache;
            this.publicFileService = publicFileService;
            this.saleReturn_DService = saleReturn_DService;
            this.productService = productService;
        }



        /// <summary>
        /// 分页查询销售退货单
        /// </summary>
        /// <param name="code"></param>
        /// <param name="status"></param>
        /// <param name="cust"></param>
        /// <param name="starttime"></param>
        /// <param name="endtime"></param>
        /// <param name="CurrentPage"></param>
        /// <returns></returns>
        [HttpGet]
        public async Task<FenYe<SaleReturn_h>> GetSaleReturn_h(string? code, int? status, int? cust, string? starttime, string? endtime,int CurrentPage)
        {
            FenYe<SaleReturn_h> fenYe = new FenYe<SaleReturn_h>()
            {
                CurrentPage =CurrentPage,
            };
            return await saleReturn_HService.GetSaleReturn_h(fenYe, code, status, cust, starttime, endtime);
        }


        /// <summary>
        /// 刷新缓存
        /// </summary>
        /// <param name="code"></param>
        /// <param name="status"></param>
        /// <param name="cust"></param>
        /// <param name="starttime"></param>
        /// <param name="endtime"></param>
        /// <param name="CurrentPage"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult Refresh(string? code, int? status, int? cust, string? starttime, string? endtime, int CurrentPage)
        {
            //缓存键
            string key = "saleReturn_h" + code + status + cust + starttime + endtime + CurrentPage;

            // 清除缓存键
            distributedCache.Remove(key);

            // 返回成功消息
            return Ok(new { success = true, message = "ok" });
        }


        /// <summary>
        /// 高级查询
        /// </summary>
        /// <param name="code"></param>
        /// <param name="starttotal"></param>
        /// <param name="endtotal"></param>
        /// <param name="startdate"></param>
        /// <param name="enddate"></param>
        /// <param name="startnum"></param>
        /// <param name="endnum"></param>
        /// <param name="status"></param>
        /// <param name="cust"></param>
        /// <param name="custlink"></param>
        /// <param name="salecode"></param>
        /// <param name="dep"></param>
        /// <param name="user"></param>
        /// <param name="createname"></param>
        /// <param name="startcreatetime"></param>
        /// <param name="endcreatetime"></param>
        /// <param name="approvername"></param>
        /// <param name="startapprovertime"></param>
        /// <param name="endapprovertime"></param>
        /// <param name="CurrentPage"></param>
        /// <returns></returns>
        [HttpGet]
        public async Task<FenYe<SaleReturn_h>> GetAdvancedSaleReturn_h(string? code, string? starttotal, string? endtotal, string? startdate, string? enddate, string? startnum, string? endnum, int? status, int? cust, string? custlink, string? salecode, int? dep, int? user, string? createname, string? startcreatetime, string? endcreatetime, string? approvername, string? startapprovertime, string? endapprovertime, int CurrentPage)
        {
            FenYe<SaleReturn_h> fenYe = new FenYe<SaleReturn_h>()
            {
                CurrentPage = CurrentPage,
            };
            return await saleReturn_HService.GetAdvancedSaleReturn_h(fenYe, code, starttotal, endtotal, startdate, enddate, startnum, endnum, status, cust, custlink, salecode, dep, user, createname, startcreatetime, endcreatetime, approvername, startapprovertime, endapprovertime);
        }



        /// <summary>
        /// 添加销售退货单
        /// </summary>
        /// <param name="addSaleReturn_HPayload"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<int> AddSaleReturn_h(AddSaleReturn_hPayload payload)
        {
            //开启事务
            using var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled);
            try
            {
                //业务逻辑
                //1.添加主销售退货单
                var id = await saleReturn_HService.AddSaleReturn_h(payload.saletData);//返回的是当前主键

                //2.添加销售退货明细
                foreach (var details in payload.saletDetails)
                {
                    var saleReturn_d = new SaleReturn_d
                    {
                        salet_id = id,
                        saled_id = details.saled_id,
                        proc_id = details.proc_id,
                        proc_name = details.proc_name,
                        saletd_num = details.saletd_num,
                        saletd_price = details.saletd_price,
                        saletd_instockOK_num = details.saletd_instockOK_num,
                        saletd_instockNO_num = details.saletd_instockNO_num,
                        saletd_total = details.saletd_total,
                        remark = details.remark,
                    };
                    await saleReturn_DService.AddSaleReturn_d(saleReturn_d);

                    var updateKyInventoryDto = new UpdateinventoryDto
                    {
                        proc_id = details.proc_id,
                        proc_inventory = 0,                 // 总库存此时不变
                        proc_ky_inventory = details.saletd_num, // 要增加的可用库存数量
                        proc_inventory_money = 0            // 库存总金额此时不变
                    };

                    // 调用服务减少可用库存
                    await productService.Updateinventory(updateKyInventoryDto);
                }

                //3.添加附件
                foreach (var item in payload.attachments)
                {
                    await publicFileService.AddFile(item);
                }
                scope.Complete();//提交事务
                return id; // 返回主入库单ID表示成功
            }
            catch (Exception ex)
            {
                //出错自动回滚
                Console.WriteLine(ex.Message);
                return 0;
            }
        }


        /// <summary>
        /// 根据id查询信息
        /// </summary>
        /// <param name="saletid"></param>
        /// <returns></returns>
        [HttpGet]
        public async Task<SaleReturn_h> GetSaleReturn_hById(int saletid)
        {
            return await saleReturn_HService.GetSaleReturn_hById(saletid);
        }


        /// <summary>
        /// 修改销售退货单
        /// </summary>
        /// <param name="payload"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<int> UpdateSaleReturn_h(UpdateSaleReturn_hPayload payload)
        {
            // 开启事务
            using var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled);
            try
            {
                // 1. 修改主销售退货单
                await saleReturn_HService.UpdateSaleReturn_h(payload.saletData);

                // 2. 修改明细
                // 2.1 获取所有旧明细，并存入字典方便查找
                var oldDetails = await saleReturn_DService.GetSaleReturn_Ds(payload.saletData.salet_id);
                var oldDetailsMap = oldDetails.ToDictionary(d => d.saletd_id);

                // 2.2 从前端提交的数据中获取到新的明细
                var newDetails = payload.saletDetails;
                var newDetailsIds = newDetails.Where(d => d.saletd_id > 0).Select(d => d.saletd_id).ToList();

                // 2.3 处理被删除的明细 (ID在旧的不在新的)
                var idsToDelete = oldDetailsMap.Keys.Except(newDetailsIds).ToList();
                if (idsToDelete.Any())
                {
                    foreach (var id in idsToDelete)
                    {
                        var deletedDetail = oldDetailsMap[id];
                        // 将删除的明细所占用的库存返还（即减去）
                        var updateKyInventoryDto = new UpdateinventoryDto
                        {
                            proc_id = deletedDetail.proc_id,
                            proc_inventory = 0,
                            proc_ky_inventory = deletedDetail.saletd_num, // 减少可用库存
                            proc_inventory_money = 0
                        };
                        await productService.UpdateinventoryJian(updateKyInventoryDto);

                        // 从数据库删除这条明细
                        await saleReturn_DService.DeleteSaleReturn_d(id);
                    }
                }

                // 2.4 遍历所有提交的明细，进行新增或修改
                foreach (var detail in newDetails)
                {
                    if (detail.saletd_id > 0) // saletd_id > 0 表示是已存在的项，需要修改
                    {
                        if (oldDetailsMap.TryGetValue(detail.saletd_id, out var oldDetail))
                        {
                            // 计算新旧数量的差值
                            int quantityDifference = detail.saletd_num - oldDetail.saletd_num;

                            if (quantityDifference != 0)
                            {
                                // 根据差值更新库存
                                var updateKyInventoryDto = new UpdateinventoryDto
                                {
                                    proc_id = detail.proc_id,
                                    proc_inventory = 0,
                                    proc_ky_inventory = quantityDifference, // 应用库存变化量
                                    proc_inventory_money = 0
                                };
                                await productService.Updateinventory(updateKyInventoryDto);
                            }

                            // 更新数据库中的明细记录
                            await saleReturn_DService.UpdateSaleReturn_d(detail);
                        }
                    }
                    else // saletd_id <= 0 表示是新增的项
                    {
                        detail.salet_id = payload.saletData.salet_id;
                        await saleReturn_DService.AddSaleReturn_d(detail);

                        // 为新增的明细增加库存
                        var updateKyInventoryDto = new UpdateinventoryDto
                        {
                            proc_id = detail.proc_id,
                            proc_inventory = 0,
                            proc_ky_inventory = detail.saletd_num, // 增加可用库存
                            proc_inventory_money = 0
                        };
                        await productService.Updateinventory(updateKyInventoryDto);
                    }
                }

                // 3. 修改附件 (先删后增的方式虽然效率不高，但逻辑简单，这里保持不变)
                var filelist = payload.attachments;
                if (filelist != null && filelist.Any())
                {
                    await publicFileService.DeleteFile(filelist[0].business_type, filelist[0].business_code);
                    foreach (var item in filelist)
                    {
                        await publicFileService.AddFile(item);
                    }
                }

                scope.Complete(); // 提交事务
                return 1;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                return 0; // 发生异常，事务回滚
            }
        }



        /// <summary>
        /// 删除进货退货单
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpPut]
        public async Task<int> DeleteSaleReturn_h(int id)
        {
            return await saleReturn_HService.DeleteSaleReturn_h(id);
        }


        /// <summary>
        /// 撤销
        /// </summary>
        /// <param name="saletid"></param>
        /// <param name="status"></param>
        /// <returns></returns>
        [HttpPut]
        public async Task<int> UpdateStatus(int saletid, int status)
        {
            return await saleReturn_HService.UpdateStatus(saletid, status);
        }



        /// <summary>
        /// 审核
        /// </summary>
        /// <param name="saletid"></param>
        /// <param name="status"></param>
        /// <param name="approvername"></param>
        /// <param name="approvertime"></param>
        /// <returns></returns>
        [HttpPut]
        public async Task<int> ApproverSaleReturn_h(int saletid, int status, string approvername, string approvertime)
        {
            return await saleReturn_HService.ApproverSaleReturn_h(saletid,status, approvername, approvertime);
        }


        /// <summary>
        /// 查询所有单据
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public async Task<List<SaleReturn_h>> GetAllSaleReturn_h()
        {
            return await saleReturn_HService.GetAllSaleReturn_h();
        }


        /// <summary>
        /// 根据关联单号查询退货记录
        /// </summary>
        /// <param name="salecode"></param>
        /// <returns></returns>
        [HttpGet]
        public async Task<List<SaleReturn_h>> GetSaleReturn_hs(string salecode)
        {
            return await saleReturn_HService.GetSaleReturn_hs(salecode);
        }
    }
}
